package com.jt.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.jt.mapper.ItemCatMapper;
import com.jt.pojo.Item;
import com.jt.pojo.ItemCat;
import com.jt.service.ItemCatService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.lang.annotation.Target;
import java.util.*;

@Service
public class ItemCatServiceImpl implements ItemCatService {
    @Autowired
    private ItemCatMapper itemCatMapper;

    /**
     * 优化手段:
     *      思路:获取所有的数据库记录,之后按照父子级关系进行封装
     *      数据结构: Map<k,v>
     *               Map<parentId,List当前父级的子级信息(不嵌套)>
     *      例子:     Map<0,List[{id=1,name="xx",children=null}.....]>
     *
     * 封装数据规则:
     *      1.遍历所有的数据.
     *      2.获取parentId
     *      3.判断parentId是否存在,之后实现数据封装
     */

    public Map<Integer,List<ItemCat>> getMap(){
        Map<Integer,List<ItemCat>> map = new HashMap<>();
        //查询所有的数据库记录
        List<ItemCat> list = itemCatMapper.selectList(null);
        //1.遍历数据
        for(ItemCat itemCat:list){
            //获取parentId
            int parentId = itemCat.getParentId();
            if(map.containsKey(parentId)){  //判断集合中是否有key
                //表示数据存在,将自己追加
                map.get(parentId).add(itemCat);
            }else{
                //key不存在, 定义list集合,将自己作为第一个元素追加
                List<ItemCat> childrenList = new ArrayList<>();
                childrenList.add(itemCat);
                //将数据保存到map集合中
                map.put(parentId,childrenList);
            }
        }
        return map;
    }

    //该方法获取1-2级数据信息
    public List<ItemCat> getTwoList(Map<Integer,List<ItemCat>> map){
        //1.先查询一级菜单数据
        List<ItemCat> oneList = map.get(0);
        //2.遍历每个一级菜单去封装二级数据
        for(ItemCat oneItemCat : oneList){
            //parent_id = 一级ID
            int parentId = oneItemCat.getId();
            //查询二级数据
            List<ItemCat> twoList = map.get(parentId);
            oneItemCat.setChildren(twoList);
        }
        return oneList;
    }
    //该方法获取1-2-3级数据信息
    public List<ItemCat> getThreeList(Map<Integer, List<ItemCat>> map) {
        //因为二级菜单是封装在一级菜单里 所以这里是返回的一级菜单
        List<ItemCat> oneList = getTwoList(map);
        //遍历一级菜单
        for(ItemCat oneItemCat : oneList){
            List<ItemCat> twoList = oneItemCat.getChildren();
            //判断二级菜单是否为空
            if(twoList == null || twoList.size() == 0){//根据业务，if里的条件也要有顺序 null在前
                continue;//跳过本次循环继续执行下一次循环
            }
            //遍历二级菜单
            for (ItemCat twoItemCat : twoList){
                Integer parentId = twoItemCat.getId();
                List<ItemCat> threeList = map.get(parentId);//通过get（key）拿到value 拿到三级菜单
                //将三级菜单封装到二级菜单中
                twoItemCat.setChildren(threeList);
            }
        }
        return oneList;
    }


    @Override
    public List<ItemCat> findItemCatList(Integer level) {
        long startTime = System.currentTimeMillis();
        //获取所有集合数据
        Map<Integer,List<ItemCat>> map = getMap();
        if(level == 1){
            //1.一级商品分类信息
            return map.get(0);
        }
        if(level == 2){ //获取一级菜单和二级菜单
            return getTwoList(map);
        }
        List<ItemCat> threeList =  getThreeList(map);
        long endTime = System.currentTimeMillis();
        System.out.println("耗时"+(endTime - startTime)+"毫秒");
        return threeList;
    }

    @Override
    @Transactional //提交事务
    public void saveItemCat(ItemCat itemCat) {
        itemCat.setStatus(true);
                 //应用自动填充
                 //.setCreated(new Date())
                //.setUpdated(new Date());
        itemCatMapper.insert(itemCat);
    }

    @Override
    @Transactional
    public void deleteItemCat(ItemCat itemCat) {
        QueryWrapper<ItemCat> queryWrapper = new QueryWrapper<>();
        if(itemCat.getLevel() == 3){//直接删除
             itemCatMapper.deleteById(itemCat.getId());
             return;
         }
        if(itemCat.getLevel() == 2){//先删三级 在删二级
            //sql： xxx where parent_id = 二级id
            queryWrapper.eq("parent_id", itemCat.getId());
            itemCatMapper.delete(queryWrapper);//删除三级菜单
            itemCatMapper.deleteById(itemCat.getId());//删除二级菜单
            return;
        }
        //删除一级菜单
        //1.查询二级菜单
        queryWrapper.eq("parent_id", itemCat.getId());
        List twoIdList = itemCatMapper.selectObjs(queryWrapper);//获取主键
        if(twoIdList.size() >0){//有数据就执行一下操作，没有就直接删除一级菜单
            queryWrapper.clear();
            //sql xxx where parent_id = 二级id 这里用in 就省去了for循环，只要包含在其中就直接删除
            queryWrapper.in("parent_id", twoIdList);
            itemCatMapper.delete(queryWrapper);
            //把1-2级封装到一个list集合中
            twoIdList.add(itemCat.getId());
            itemCatMapper.deleteBatchIds(twoIdList);//把1-2级都删除
        }else {
            itemCatMapper.deleteById(itemCat.getId());//二级没有数据直接删除一级
        }
    }

    @Override
    @Transactional
    /* id当作条件，不为空的数据执行sql*/
    public void status(ItemCat itemCat) {
        itemCatMapper.updateById(itemCat);
    }

    @Override
    @Transactional
    public void updateItemCat(ItemCat itemCat) {
        //itemCat.setUpdated(new Date());时间自动填充了
        //少量数据
        ItemCat temp = new ItemCat();
        temp.setId(itemCat.getId()).setName(itemCat.getName());
        itemCatMapper.updateById(temp);
    }
    /*
     * 弊端: 由于多次循环遍历 查询数据库,导致数据库查询次数太多效率极低.
     * 思路:
     *      1.刚才的业务逻辑梳理
     *      2.如何优化?????   提高效率
     * 优化策略:
     *       降低用户查询数据库的次数.
     */
/*    @Override
    public List<ItemCat> findItemCatList(Integer level) {
        long startTime = System.currentTimeMillis();
        //查询一级商品分类信息
        QueryWrapper<ItemCat> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("parent_id",0);
        List<ItemCat> oneList = itemCatMapper.selectList(queryWrapper);
        //查询二级商品分类信息
        for(ItemCat oneItemCat: oneList){
            //1.为了复用条件构造器 将之前的数据清空
            queryWrapper.clear();
            //查询二级数据 parent_id = 一级ID
            queryWrapper.eq("parent_id",oneItemCat.getId());
            List<ItemCat> twoList = itemCatMapper.selectList(queryWrapper);
                    //遍历二级列表 查询三级数据,封装数据返回
            //将二级封装到一级
            oneItemCat.setChildren(twoList);
        }
        long endTime = System.currentTimeMillis();
        System.out.println("耗时"+(endTime - startTime)+"毫秒");
        return oneList;
    }*/
}
